package myJs.user.workflow.featureSelection.rf

import myJs.cps._
import myJs.myPkg.reactHookForm.{ReactHookForm, UseFormRT, UseFormStateOptions}
import shared.pojo.WorkflowMission._
import myJs.tool.Tool._
import com.softwaremill.quicklens._
import myJs.Implicits._
import myJs.tool.Tool

import scala.collection.immutable.SeqMap
import scala.scalajs.js

import japgolly.scalajs.react.vdom.all._
import japgolly.scalajs.react._
import japgolly.scalajs.react.React.Fragment
import japgolly.scalajs.react.util.EffectCatsEffect._
import myJs.myPkg.Hooks._
import cats.effect._
import myJs.Implicits._
import myJs.Utils._

/** Created by yz on 3/11/2020
  */
object RfCp {

  case class Props(
      curI: Int,
      data: EachRfData,
      dataChange: EachRfData => SyncIO[Unit],
      dataModifyF: (EachRfData=>EachRfData) => SyncIO[Unit],
      fsData:FsData
  ){
    @inline def render: VdomElement = {
      Component(this)
    }
  }

  val Component = ScalaFnComponent[Props] { props =>
    val curTool = Rf
    val namePrefix = s"rf.${props.curI}"

    object FTool {

      def scaleMethodChange = (v: String) => {
        val newData = props.data.modify(_.scaleMethod).setTo(v)
        props.dataChange(newData)
      }

      def groupsModifyF = (v: List[String]) => {
        val newData = modifyLens[EachRfData](_.groups).setTo(v)
        props.dataModifyF(newData)
      }

      def ntreeChange = (v: String) => {
        val newData = props.data.modify(_.ntree).setTo(v)
        props.dataChange(newData)
      }

      def replaceChange = (v: String) => {
        val newData = props.data.modify(_.replace).setTo(v)
        props.dataChange(newData)
      }

      def hasMtryChange = (v: Boolean) => {
        val newData = props.data.modify(_.hasMtry).setTo(v)
        props.dataChange(newData)
      }

      def mtryChange = (v: String) => {
        val newData = props.data.modify(_.mtry).setTo(v)
        props.dataChange(newData)
      }

      def hasNodesizeChange = (v: Boolean) => {
        val newData = props.data.modify(_.hasNodesize).setTo(v)
        props.dataChange(newData)
      }

      def nodesizeChange = (v: String) => {
        val newData = props.data.modify(_.nodesize).setTo(v)
        props.dataChange(newData)
      }

      def hasMaxnodeChange = (v: Boolean) => {
        val newData = props.data.modify(_.hasMaxnode).setTo(v)
        props.dataChange(newData)
      }

      def maxnodeChange = (v: String) => {
        val newData = props.data.modify(_.maxnode).setTo(v)
        props.dataChange(newData)
      }

      def topMChange = (v: String) => {
        val newData = props.data.modify(_.topM).setTo(v)
        props.dataChange(newData)
      }

    }
    val formState = ReactHookForm.useFormState(options =
      UseFormStateOptions(
        name = namePrefix
      )
    )
    useEffect(
      SyncIO{
        Tool.refreshNodeColor(props.data.nodeId, formState, namePrefix)
      },
      List(formState)
    )
    val dataMatrixGroups = props.fsData.dataMatrix.groups
    useEffect(
      {
        FTool.groupsModifyF(dataMatrixGroups)
      },
      List(dataMatrixGroups)
    )

    val groupMap = dataMatrixGroups.optionMap

    val replaceMap = SeqMap(
      "T" -> messages("yes"),
      "F" -> messages("no")
    )

    div(
      RSelectMulCp.Props(
        value = props.data.groups,
        label = messages("groups"),
        name = s"${namePrefix}.groups",
        optionMap = groupMap,
        onChange = FTool.groupsModifyF
      ).render,
      SelectCp.Props(
        value = props.data.scaleMethod,
        label = messages("scaleMethod"),
        name = s"${namePrefix}.scaleMethod",
        optionMap = scaleMethodMap,
        onChange = FTool.scaleMethodChange
      ).render,
      InputCp.Props(
        value = props.data.ntree,
        show = true,
        label = messages("numberOfTreesToGrow"),
        name = s"${namePrefix}.ntree",
        onChange = FTool.ntreeChange
      ).render,
      SelectCp.Props(
        value = props.data.replace,
        label = messages("samplingWithReplacement"),
        name = s"${namePrefix}.replace",
        optionMap = replaceMap,
        onChange = FTool.replaceChange
      ).render,
      ToggleCp.Props(
        value = props.data.hasMtry,
        label = messages("setVariablesNumber"),
        name = s"${namePrefix}.hasMtry",
        valueChange = FTool.hasMtryChange
      ).render,
      InputCp.Props(
        value = props.data.mtry,
        show = props.data.hasMtry,
        label = messages("variablesNumber"),
        name = s"${namePrefix}.mtry",
        onChange = FTool.mtryChange
      ).render,
      ToggleCp.Props(
        value = props.data.hasNodesize,
        label = messages("setMinimumNodesize"),
        name = s"${namePrefix}.hasNodesize",
        valueChange = FTool.hasNodesizeChange
      ).render,
      InputCp.Props(
        value = props.data.nodesize,
        show = props.data.hasNodesize,
        label = messages("nodesMinimumSize"),
        name = s"${namePrefix}.nodesize",
        onChange = FTool.nodesizeChange
      ).render,
      ToggleCp.Props(
        value = props.data.hasMaxnode,
        label = messages("setMaximumNumber"),
        name = s"${namePrefix}.hasMaxnode",
        valueChange = FTool.hasMaxnodeChange
      ).render,
      InputCp.Props(
        value = props.data.maxnode,
        show = props.data.hasMaxnode,
        label = messages("nodesMaximumNumber"),
        name = s"${namePrefix}.maxnode",
        onChange = FTool.maxnodeChange
      ).render,
      InputCp.Props(
        value = props.data.topM,
        show = true,
        label = messages("selectionTopM"),
        name = s"${namePrefix}.topM",
        onChange = FTool.topMChange
      ).render
    )

  }

}
